package com.topscomm.mpm;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.rabbitmq.client.AMQP;
import com.topscomm.base.service.impl.MarketBasicService;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.BasicSystemConst;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.basic.util.PrimaryKeyUtil;
import com.topscomm.cbo.pojo.CboApprovalFlowInsEntity;
import com.topscomm.cbo.service.impl.CboApprovalFlowInsService;
import com.topscomm.cbo.service.impl.CboApprovalNodeInsService;
import com.topscomm.main.hessian.IBaseChangeLogService;
import com.topscomm.main.hessian.IBasePropertyService;
import com.topscomm.basic.util.SQLAdapter;
import com.topscomm.cbo.pojo.CboExcelImportConfigEntity;
import com.topscomm.cbo.service.impl.CboExcelImportConfigService;
import com.topscomm.mis.MisService;
import com.topscomm.mis.util.WorkCenterUtil;
import com.topscomm.mpm.pojo.MpmPMOStandardizationRecordEntity;
import com.topscomm.mpm.pojo.MpmProjectProblemEntity;
import com.topscomm.mpm.service.impl.MpmPMOStandardizationRecordService;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;
import com.topscomm.pub.util.*;
import com.topscomm.tap.TapEntity;
import com.topscomm.tap.TapService;
import com.topscomm.tap.common.DatacodeCache;
import com.topscomm.tap.common.SessionUserBean;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.configurationprocessor.json.JSONArray;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@SuppressWarnings("rawtypes")
public class MpmService<T extends MpmEntity, TDao extends IMpmDao> extends MarketBasicService<T, TDao> implements IMpmService<T, TDao> {
    DatacodeCache datacodeCache = new DatacodeCache();
    private static final String BASEPROPERTYSCOPE = "changelog";
    @Autowired
    private IBasePropertyService basePropertyService;
    @Autowired
    private IBaseChangeLogService baseChangeLogService;
    @Autowired
    private MpmPMOStandardizationRecordService mpmPMOStandardizationRecordService;
    @Autowired
    private CboApprovalNodeInsService cboApprovalNodeInsService;
    @Autowired
    private CboApprovalFlowInsService cboApprovalFlowInsService;

    /**
     * 统一的给扩充字段赋值，第一个为单号，第二个为申请部门，第三个位申请人
     */
    @Override
    protected void afterSubmit(TapEntity entity, SessionUserBean sessionUserBean) {
        try {
            StringBufferProxy sql = new StringBufferProxy();
            sql.appendLineSingle("update CboApprovalFlowIns set ");
            sql.appendLineSingle("extendfield1 = (select docno from {0} "
                    + "where CboApprovalFlowIns.sourceid = {0}.id "
                    + "and CboApprovalFlowIns.sourcetype = '{0}'),", entity.getTableName());
            sql.appendLineSingle("extendfield2 = (select deptcode from {0} "
                    + "where CboApprovalFlowIns.sourceid = {0}.id "
                    + "and CboApprovalFlowIns.sourcetype = '{0}'),", entity.getTableName());
            sql.appendLineSingle("extendfield3 = (select usercode from {0} "
                    + "where CboApprovalFlowIns.sourceid = {0}.id "
                    + "and CboApprovalFlowIns.sourcetype = '{0}')", entity.getTableName());
            sql.appendLineSingle("where sourceid = '{0}' and sourcetype='{1}'", entity.getId(), entity.getTableName());

            this.getDao().updateExecute(sql.toString());
            super.afterSubmit(entity, sessionUserBean);
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    /**
     * @param
     * @return
     * @throws
     * @description: 生成id
     * @author xinfushuo
     * @date 2021/9/10
     * @modify
     */
    public void GenerateID(BasicEntity entity) {
        if (entity.getId() <= 0) {
            long[] arrayId = PrimaryKeyUtil.GeneIDs(entity.getTableName(), 1);
            entity.setId(arrayId[0]);
        }
    }

    /**
     * @param
     * @return
     * @throws
     * @description:
     * @author xinfushuo
     * @date 2021/9/10
     * @modify
     */
    public void GenerateDocno(BasicEntity entity) {
        long entityId = entity.getId();
        String docNo = String.valueOf(entityId);
        if (!StringUtil.isEmpty(docNo)) {
            docNo = docNo.substring(0, 6) + docNo.substring(9);
            entity.setValue("docno", docNo);
        }
    }

    /**
     * @param
     * @return
     * @throws
     * @description:
     * @author xinfushuo
     * @date 2021/9/10
     * @modify
     */
    public void GenerateCode(BasicEntity entity, String header, String codeField) {
        long entityId = entity.getId();
           String docNo = String.valueOf(entityId);
            docNo = docNo.substring(0, 6) + docNo.substring(8);
        try {
            Class<? extends Object> entityClass = entity.getClass();
            Method getprojectlevel = entityClass.getMethod("getProjectlevel");
            String projectLevel = (String) getprojectlevel.invoke(entity);
            //赋值编号 xxcode
            projectLevel = datacodeCache
                    .getValueDynamic("MpmProjectLevel", projectLevel, "code", "name");
            SimpleDateFormat sdFormat = new SimpleDateFormat("yyMMdd");
            String dateCode = sdFormat.format(new Date());
            String flowCode = docNo.substring(docNo.length() - 4);
            header = header + projectLevel + dateCode + flowCode;
            entity.setValue(codeField, header);
        } catch (Exception e) {
            throw new ServiceException(e + "编号生成错误");
        }

    }

    /**
     * @param header    : 编号头 如 PP PR PSl
     * @param codeField : 编号列名
     * @return
     * @throws
     * @description:
     * @author xinfushuo
     * @date 2021/9/2
     * @modify
     */
    @Transactional
    public void GenerateIDAndCode(BasicEntity entity, String header, String codeField) {
        try {
            //若id未生成 生成id
            if (entity.getId() <= 0) {
                GenerateID(entity);
            } else {//当id 存在时-》即保存后

                //若docno已生成 则不重复生成
                if (StringUtil.isEmpty(ConvertUtil.convertToString(entity.getValue("docno")))) {
                    GenerateDocno(entity);
                }
                // 若codeField已生成，则不重复生成
                if (StringUtil.isEmpty(ConvertUtil.convertToString(entity.getValue(codeField)))) {
                    GenerateCode(entity, header, codeField);
                }
            }
        } catch (Exception e) {
            throw new ServiceException(e + "编号id或docno生成失败");
        }
    }
    /**
     * @description: 获取basechangelog信息
     * @author houyuhang
     * @date 2023/02/03
     * @modify
     */
    protected Map<String, Object> getMainChangeLogEntity(Map<String, Object> inputMap) throws Exception {
        // 整理变量类型
        Map<String, Object> newMap = (Map<String, Object>) inputMap.get("newmap");
        Map<String, Object> oldMap = (Map<String, Object>) inputMap.get("oldmap");
        String sourceType = inputMap.get("sourcetype").toString();
        String sourceId = inputMap.get("sourceid").toString();
        String baseLogOperateType = inputMap.get("baselogoperatetype").toString();
        String topsourcetype = inputMap.get("topsourcetype").toString();
        String topsourceid = inputMap.get("topsourceid").toString();
        String newVersion = inputMap.get("version").toString();
        // 获取sourcetype对应的字段
        List<Map<String, Object>> baseProperties = basePropertyService.getBaseProperty(sourceType,
                BASEPROPERTYSCOPE);
        if (baseProperties.size() <= 0) {
            throw new ServiceException("baseproperty数据维护不正确");
        }
        // 获取标题的baseProperty
        List<Map<String, Object>> basePropertiesFilter = baseProperties.stream()
                .filter(item -> item.get("sourcetype").toString().equals(sourceType)
                        && item.get("datatype").toString().equals(MpmSystemConst.BasePropertyDataTypeEnum.Title))
                .collect(Collectors.toList());
        if (basePropertiesFilter.size() <= 0) {
            throw new ServiceException("baseproperty数据维护不正确");
        }
        Map<String, Object> titleBaseProperty = basePropertiesFilter.get(0);
        // 获取当前表的是否有分类信息的分类字段
        String sourceKindKey = "";
        String kindTitle = "";
        if (titleBaseProperty.get("relationkind") != null
                && !StringUtil.isEmpty(ConvertUtil.convertToString(titleBaseProperty.get("relationkind")))) {
            org.json.JSONArray kindJsonArray = new org.json.JSONArray(
                    ConvertUtil.convertToString(titleBaseProperty.get("relationkind")));
            org.json.JSONObject jsonObject = kindJsonArray.getJSONObject(0);
            sourceKindKey = ConvertUtil.convertToString(jsonObject.get("kindkey"));
            if (!sourceKindKey.equals("") && newMap.containsKey(sourceKindKey)
                    && newMap.get(sourceKindKey) != null) {
                String kindValue = ConvertUtil.convertToString(newMap.get(sourceKindKey));
                for (int i = 0; i < kindJsonArray.length(); i++) {
                    org.json.JSONObject obj = kindJsonArray.getJSONObject(i);
                    if (ConvertUtil.convertToString(obj.get("kindvalue")).equals(kindValue)) {
                        kindTitle = ConvertUtil.convertToString(obj.get("kindtitle"));
                    }
                }
            }
        }
        // 组装变更记录数据
        String content = baseChangeLogService.compareDataForMpm(oldMap, newMap, baseProperties, baseLogOperateType);
        // 如果没有变更数据
        if (StringUtil.isEmpty(content) || "[]".equals(content)) {
            return null;
        }
        // 企业客户、个人客户要更新version
        Map<String, Object> baseChangeLogEntity = new HashMap<>();
        baseChangeLogEntity.put("sourcetype", sourceType);
        baseChangeLogEntity.put("sourceid",sourceId);
        baseChangeLogEntity.put("topsourcetype", topsourcetype);
        baseChangeLogEntity.put("topsourceid", topsourceid);
        if (!StringUtil.isEmpty(newVersion)) {
            baseChangeLogEntity.put("version", Integer.parseInt(newVersion));
        }
        try {
            baseChangeLogEntity.put("title", this.getTitle(baseLogOperateType, kindTitle, titleBaseProperty, newMap));
        } catch (Exception e) {
            baseChangeLogEntity.put("title", "信息");
        }
        baseChangeLogEntity.put("username", this.getSessionUserBean().getUser().getName());
        baseChangeLogEntity.put("usercode", this.getSessionUserBean().getUser().getCode());
        baseChangeLogEntity.put("operatetype", baseLogOperateType);
        baseChangeLogEntity.put("content", content);
        // 如果存在sourceKindKey
        if (!sourceKindKey.equals("") && newMap.containsKey(sourceKindKey) && newMap.get(sourceKindKey) != null) {
            baseChangeLogEntity.put("sourcekind", ConvertUtil.convertToString(newMap.get(sourceKindKey)));
        }
        if (inputMap.containsKey("description") && inputMap.get("description") != null) {
            baseChangeLogEntity.put("description", inputMap.get("description").toString());
        }
        return baseChangeLogEntity;
    }

    /**
     * @param baselogoperatetype
     * @param kindTitle
     * @param titleBaseProperty
     * @return java.lang.String
     * @description: 获取标题
     * @author: wangxinhua
     * @date: 2020/12/2 18:46
     * @modify:
     */
    private String getTitle(String baselogoperatetype, String kindTitle, Map<String, Object> titleBaseProperty,
                            Map<String, Object> newMap) {
        StringBuilder title = new StringBuilder();
        switch (baselogoperatetype) {
            case MpmSystemConst.BaseLogOperateTypeEnum.Add:
                title.append("新增");
                break;
            case MpmSystemConst.BaseLogOperateTypeEnum.Edit:
                title.append("编辑");
                break;
            case MpmSystemConst.BaseLogOperateTypeEnum.Del:
                title.append("删除");
                break;
            default:
                break;
        }
        title.append(" \"");
        title.append(parsingTitle(titleBaseProperty.get("name").toString(), newMap));
        if (!StringUtil.isEmpty(kindTitle)) {
            title.append("-");
            title.append(kindTitle);
        }
        title.append("\"");
        return title.toString();
    }
    /**
     * @description: 解析带有{}的标题
     * @param baseTitle
     * @param newMap
     * @return java.lang.String
     * @author: wangxinhua
     * @date: 2020/12/19 14:21
     * @modify:
     */
    private String parsingTitle(String baseTitle, Map<String, Object> newMap) {
        String regex = "\\{([^}])*\\}";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(baseTitle);
        ArrayList<String> replaceKeys = new ArrayList<String>();
        while (matcher.find()) {
            String key = matcher.group();
            String formatKey = key.replace("{", "");
            formatKey = formatKey.replace("}", "");
            if (newMap.containsKey(formatKey) && newMap.get(formatKey) != null) {
                baseTitle = baseTitle.replace(key, newMap.get(formatKey).toString());
            } else {
                baseTitle = baseTitle.replace(key, "");
            }
        }
        return baseTitle;
    }
    /**
     * @description: 获取对应项目PMO和省区PMO信息
     * @author: houyuhang
     * @date: 2023/02/06
     * @modify:
     */
    public List<Map<String, Object>> getMessageReceiverPMO(String deptcommoncode) {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" instr(',' || chargedeptcommoncode || ',', ',' || '{0}' || ',') > 0 ",deptcommoncode);
        return mpmPMOStandardizationRecordService.queryMapByWhere(sql.toString());
    }
    /**
     * @Author wangjielei
     * @Description 导入数据处理--FDS专用
     * @Date 2022/11/30 14:55
     * @Param [paraMap, attachFile]
     * @return java.util.List<java.util.Map<java.lang.String,java.lang.String>>
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int executeImportDataExcel(Map<String, Object> paraMap, File attachFile) {
        String tableName = ConvertUtil.convertToString(paraMap.get("tableName"));
        // 处理异常抛出错误信息统一处理  --注意：如果重写数据接口存在自定义异常则需要拼接,统一格式为
        StringBufferProxy throwStringMessage = new StringBufferProxy();
        if (tableName.length() == 0) {
            throw new ServiceException("请联系管理员配置数据库表");
        }
        CboExcelImportConfigService configService = (CboExcelImportConfigService) SpringUtil
                .getBean("cboExcelImportConfigService");
        List<CboExcelImportConfigEntity> listConfig = configService.queryByWhere("tablename='" + tableName + "'");
        if (listConfig == null || listConfig.size() < 1) {
            throw new ServiceException("没有维护excel导入配置，表名为：" + tableName);
        }
        // excel有效起始行
        int importStartRow = ConvertUtil.convertToInt(listConfig.get(0).getStartrow());
        // 导入字段映射关系json格式
        String importFields = listConfig.get(0).getRelationships();
        // 必填字段
        String requiredFields = listConfig.get(0).getRequiredfields();
        // 填充数据
        String expandJsonDate = listConfig.get(0).getSupplement();
        // 转换字段
        String convertFields = listConfig.get(0).getConvertfields();
        Map<String, String> convertFieldsMap = (Map<String, String>) JSONUtil.parseJSONString(convertFields);
        // 唯一字段
        String uniqueFields = listConfig.get(0).getUniquefields();
        // 字段描述
        String descFields = listConfig.get(0).getDescfields();
        Map<String, String> fieldDescMap = (Map<String, String>) JSONUtil.parseJSONString(descFields);
        // 读取业务数据
        List<Map<String, String>> listDataMap;
        try {
            listDataMap = OfficeOperateUtil.parseExcel(attachFile, attachFile.getName(), importFields, importStartRow);
        } catch (Exception e) {
            throw new ServiceException("excel读取失败");
        }
        // 删除无效行数据
        this.removeNoValidRow(listDataMap);
        if (ObjectUtil.isEmpty(listDataMap)) {
            throw new ServiceException("excel表没有数据，请填写数据");
        }
        // 转换字段
        this.convertExcelData(listDataMap, convertFieldsMap);
        // 自定义输入处理
        this.expandInputExcelData(listDataMap, paraMap, throwStringMessage);
        // 扩展处理，可以重写接口，实现特殊处理
        this.expandProcessExcelData(listDataMap, throwStringMessage);
        // 与数据库校验，校验长度、数据库类型是否合法
        this.checkDataBaseFieldValid(listDataMap, importStartRow, throwStringMessage);
        // 必填项校验
        this.checkDataRequired(listDataMap, requiredFields, fieldDescMap, importStartRow, throwStringMessage);
        // 唯一性校验
        this.checkDataUnique(listDataMap, uniqueFields, fieldDescMap, importStartRow, throwStringMessage);
        // 首先抛出合法性和必填校验错误，否则后续数据处理存在风险
        if(!StringUtil.isEmpty(throwStringMessage.toString())){
            throw new ServiceException("导入失败，" + throwStringMessage.toString() + "请填写准确完整后重新导入。");
        }
        // 处理补充数据
        this.addDefaultData(expandJsonDate, listDataMap);
        // 映射编码
        this.dealCode(listDataMap, importStartRow, throwStringMessage);
        // 如果存在异常信息则直接抛出异常
        if(!StringUtil.isEmpty(throwStringMessage.toString())){
            throw new ServiceException("导入失败，" + throwStringMessage.toString() + "请填写准确完整后重新导入。");
        }
        // 数据入库
        this.executeInsertExcelData(listDataMap);
        return listDataMap.size();
    }
    /**
     * @description: // 删除无效行数据
     * @param: [listDataMap]
     * @return:
     * @author: houyuhang
     * @date: 2023/02/14
     * @modify:
     */
    public void removeNoValidRow(List<Map<String, String>> listDataMap) {
        for (int i = 0; i < listDataMap.size();) {
            Map<String, String> map = listDataMap.get(i);
            boolean isExistValid = false;
            for (Map.Entry<String, String> entry : map.entrySet()) {
                String mapValue = entry.getValue();
                if (mapValue.length() > 0) {
                    isExistValid = true;
                }
            }
            if (isExistValid) {
                i++;
            } else {
                listDataMap.remove(i);
            }
        }
    }

    public void expandInputExcelData(List<Map<String, String>> listDataMap, Map<String, Object> paraMap, StringBufferProxy throwStringMessage) {

    }

    public void expandProcessExcelData(List<Map<String, String>> list, StringBufferProxy throwStringMessage) {
    }
    /**
     * @description: // 与数据库校验，校验长度、数据库类型是否合法
     * @param: [listDataMap, importStartRow]
     * @return:
     * @author: wanghjielei
     * @date: 2022/11/17 14:26
     * @modify:
     */
    public void checkDataBaseFieldValid(List<Map<String, String>> listDataMap, int importStartRow, StringBufferProxy throwStringMessage) {
        // 得到数据库字段map
        Map<String, Map<String, String>> filedsInfo = this.getDataBaseField();
        // 判断excel数据是否合法，通过长度、类型判断
        for (int i = 0; i < listDataMap.size(); i++) {
            Map<String, String> map = listDataMap.get(i);
            StringBufferProxy message = new StringBufferProxy();
            String info = "第" + (i + importStartRow) + "行记录：";
            for (Map.Entry<String, String> entry : map.entrySet()) {
                String mapValue = ConvertUtil.convertToString(entry.getValue());
                String mapKey = entry.getKey().toLowerCase();
                if (filedsInfo.containsKey(mapKey)) {
                    Map fieldMap = filedsInfo.get(mapKey);
                    int maxLength = ConvertUtil.convertToInt(fieldMap.get("dataLength"));
                    String dataType = ConvertUtil.convertToString(fieldMap.get("dataType"));
                    if (fieldConvertType(mapKey,
                            SQLAdapter.toFieldDataType(dataType)) == BasicSystemConst.BasicDbFieldTypeEnum.CharType) {// 字符类型
                        if (mapValue.length() > maxLength) {
                            message.appendSingle("【" + mapValue + "】" + "超长了，最大长度为" + maxLength + "；");
                            // throw new ServiceException(info + "【" + mapValue + "】" + "超长了，最大长度为" + maxLength);
                        }
                    }
                    if (fieldConvertType(mapKey,
                            SQLAdapter.toFieldDataType(dataType)) == BasicSystemConst.BasicDbFieldTypeEnum.IntType) {// 数值类型
                        // 正负数值类型均可导入
                        Pattern pattern = Pattern.compile("^-?[0-9]\\d*(\\.\\d+)?$");
                        // 此处单独处理数字类型，控制不再判断
                        if (!ObjectUtil.isEmpty(mapValue) && !pattern.matcher(mapValue).matches()) {
                            message.appendSingle("【" + mapValue + "】" + "是非数值类型；");
                            // throw new ServiceException(info + "【" + mapValue + "】" + "是非数值类型，请修改");
                        }
                    }
                    if (fieldConvertType(mapKey,
                            SQLAdapter.toFieldDataType(dataType)) == BasicSystemConst.BasicDbFieldTypeEnum.DateType) {// 日期类型
                        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                        try {
                            format.setLenient(false);
                            format.parse(mapValue);
                        } catch (ParseException e) {
                            message.appendSingle("【" + mapValue + "】" + "是非日期类型格式；");
                            // throw new ServiceException(info + "【" + mapValue + "】" + "非日期类型格式，请修改");
                        }
                    }
                }
            }
            if(!StringUtil.isEmpty(message.toString())){
                throwStringMessage.appendSingle(info);
                throwStringMessage.appendSingle(message.toString());
            }
        }
    }
    /**
     * @Author wangjielei
     * @Description 必填项校验
     * @Date 2022/12/2 11:13
     * @Param [listDataMap, requiredFields, fieldDescMap, importStartRow]
     * @return void
     **/
    public void checkDataRequired(List<Map<String, String>> listDataMap, String requiredFields,
                                  Map<String, String> fieldDescMap, int importStartRow, StringBufferProxy throwStringMessage) {
        if (listDataMap == null || listDataMap.size() == 0 || StringUtil.isEmpty(requiredFields)) {
            return;
        }
        String[] requiredFieldsArray = requiredFields.split(",");
        // 校验是否必填
        for (int i = 0; i < listDataMap.size(); i++) {
            Map<String, String> map = listDataMap.get(i);
            StringBufferProxy message = new StringBufferProxy();
            String info = "第" + (i + importStartRow) + "行记录：";
            for (String fieldCode : requiredFieldsArray) {
                if (StringUtil.isEmpty(map.get(fieldCode))) {
                    message.appendSingle(fieldDescMap.get(fieldCode));
                    message.appendSingle("、");
                    // throw new ServiceException(info + fieldDescMap.get(fieldCode) + "必填");
                }
            }
            if(!StringUtil.isEmpty(message.toString())){
                throwStringMessage.appendSingle(info);
                throwStringMessage.appendSingle(message.toString().substring(0, message.length()-1));
                // 此处记录报错是编码映射不对报错或必填项没填报错
                throwStringMessage.appendSingle("填写错误；");
            }
        }
    }
    /**
     * @Author wangjielei
     * @Description 唯一性校验
     * @Date 2022/12/2 11:18
     * @Param [listDataMap, uniqueFields, fieldDescMap, importStartRow, throwStringMessage]
     * @return void
     **/
    public void checkDataUnique(List<Map<String, String>> listDataMap, String uniqueFields,
                                Map<String, String> fieldDescMap, int importStartRow, StringBufferProxy throwStringMessage) {
        if (listDataMap == null || listDataMap.size() == 0 || StringUtil.isEmpty(uniqueFields)) {
            return;
        }
        String[] uniqueFieldNameArray = uniqueFields.split(",");
        Map<String, String> currentFieldMap = new HashMap<>();
        // excel表数据自身是否重复
        StringBufferProxy tipInfo = new StringBufferProxy();
        for (int i = 0; i < listDataMap.size() - 1; i++) {
            Map<String, String> map1 = listDataMap.get(i);
            for (int j = listDataMap.size() - 1; j > i; j--) {
                Map<String, String> map2 = listDataMap.get(j);
                for (String uniqueFieldName : uniqueFieldNameArray) {
                    // 拼接多个字段作为唯一标识
                    String[] fieldNames = uniqueFieldName.split("-");
                    StringBufferProxy repeatInfo = new StringBufferProxy();
                    boolean isRepeat = true;
                    for (String fieldName : fieldNames) {
                        if ((!StringUtil.isEmpty(map1.get(fieldName)))
                                && map1.get(fieldName).equals(map2.get(fieldName))) {
                            repeatInfo.appendSingle(map2.get(fieldName) + "  ");
                        } else {
                            isRepeat = false;
                            break;
                        }
                    }
                    if (isRepeat == true) {
                        tipInfo.appendLineSingle(repeatInfo.toString());
                    }

                }
            }
        }
        if (tipInfo.length() > 0) {
            throwStringMessage.appendSingle("excel表中如下数据：" + tipInfo.toString() + "重复");
            throwStringMessage.appendSingle("; ");
            // throw new ServiceException("excel表中如下数据：" + tipInfo.toString() + "重复");
        }
        Map<String, Map<String, String>> filedsInfo = this.getDataBaseField();
        // 得到某个字段所有值，进行拼接
        for (int i = 0; i < listDataMap.size(); i++) {
            Map<String, String> mapRow = listDataMap.get(i);
            for (String uniqueFieldName : uniqueFieldNameArray) {
                String[] fieldNames = uniqueFieldName.split("-");
                for (String fieldName : fieldNames) {
                    if (StringUtil.isEmpty(currentFieldMap.get(fieldName))) {
                        if (filedsInfo.get(fieldName) != null && SQLAdapter.toFieldDataType(// 日期类型特殊处理
                                filedsInfo.get(fieldName).get("dataType")) == BasicSystemConst.BasicDbFieldTypeEnum.DateType) {
                            currentFieldMap.put(fieldName, SQLAdapter.toDateLong(mapRow.get(fieldName)));
                        } else {
                            currentFieldMap.put(fieldName, "'" + mapRow.get(fieldName) + "'");
                        }
                    } else {
                        if (filedsInfo.get(fieldName) != null && SQLAdapter.toFieldDataType(
                                filedsInfo.get(fieldName).get("dataType")) == BasicSystemConst.BasicDbFieldTypeEnum.DateType) {
                            currentFieldMap.put(fieldName, currentFieldMap.get(fieldName) + ","
                                    + SQLAdapter.toDateLong(mapRow.get(fieldName)));
                        } else {
                            currentFieldMap.put(fieldName,
                                    currentFieldMap.get(fieldName) + ",'" + mapRow.get(fieldName) + "'");
                        }

                    }
                }
            }
        }
        // 与数据库判断重复性
        tipInfo.clear();
        /*
         * for (String uniqueFieldName : uniqueFieldNameArray) { // 拼接多个字段作为唯一标识
         * String[] fieldNames = uniqueFieldName.split("+"); for (String
         * fieldName : fieldNames) {
         *
         * } }
         */
        for (Map.Entry<String, String> entry : currentFieldMap.entrySet()) {
            StringBufferProxy sql = new StringBufferProxy();
            sql.appendSingle(" 1=1 ");
            sql.appendLineSingle(" and {0} in ({1})", entry.getKey(), entry.getValue());
            List<Map<String, Object>> queryList = this.queryMapByWhere(sql.toString());
            for (Map itemMap : queryList) {
                tipInfo.appendLineSingle(ConvertUtil.convertToString(itemMap.get(entry.getKey())));
            }
        }
        if (tipInfo.length() > 0) {
            throwStringMessage.appendSingle("如下数据：" + tipInfo.toString() + "与数据库中数据重复");
            throwStringMessage.appendSingle("; ");
            // throw new ServiceException("如下数据：" + tipInfo.toString() + "与数据库中数据重复");
        }
    }
    /**
     * @Author wangjielei
     * @Description 导入编码映射
     * @Date 2022/11/30 14:55
     * @Param [listDataMap]
     * @return void
     **/
    public void dealCode(List<Map<String, String>> listDataMap, int importStartRow, StringBufferProxy throwStringMessage) {}

    /**
     * @Author houyuhang
     * @Description 根据sourceid和sourcetype删除flowins、nodeins表数据
     * @Date 2023/02/25
     * @return void
     **/
    public void delCboApprovalInsInfo(String sourcetype, String sourceid) {
        if (StringUtil.isEmpty(sourceid) || StringUtil.isEmpty(sourcetype)) {
            return;
        }
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" sourcetype = '{0}' and sourceid in ({1}) ", sourcetype, sourceid);
        CboApprovalFlowInsEntity cboApprovalFlowInsEntity = cboApprovalFlowInsService.queryObjectByWhere(sql.toString());
        if (ObjectUtil.isEmpty(cboApprovalFlowInsEntity)) {
            return;
        }
        cboApprovalNodeInsService.deleteByWhere(sql.toString());
        cboApprovalFlowInsService.deleteByWhere(sql.toString());
        //发送取消消息
        WorkCenterUtil.sendFlowInsDelMQ(ConvertUtil.convertToString(cboApprovalFlowInsEntity.getId()));
    }
}
